home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / b / b.lha / B / src / bint / b3fil.c < prev    next >
C/C++ Source or Header  |  1988-11-24  |  7KB  |  303 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2.  
  3. /*
  4.   $Header: b3fil.c,v 1.4 85/08/27 10:56:00 timo Exp $
  5. */
  6.  
  7. /* Facilities supplied by the file system */
  8.  
  9. #include "b.h"
  10. #include "b0con.h"
  11. #include "b0fea.h"
  12. #include "b0fil.h"
  13. #include "b1obj.h"
  14. #include "b3scr.h"
  15. #include "b3err.h"
  16. #include "b3fil.h"
  17.  
  18. #ifndef INTEGRATION
  19.  
  20. /*This file defines the facilities needed for dealing with files,
  21.   apart from C's standard I/O facilities which are used throughout the system.
  22.  
  23.   Units are held on files in a 'workspace', which on Unix is modelled
  24.   using directories. The function 'f_uname' converts a unit name into a
  25.   unique filename. On Unix this is done by prepending a character to the unit
  26.   name to indicate the kind of unit (for how'to ', and for tests and yields
  27.   < for zeroadic, " for monadic and > for dyadic; these have been chosen as
  28.   characters that are not usually used in filenames), and truncating the
  29.   name if necessary. If the name does have to be truncated, then it is
  30.   hashed to produce a character that is appended to the filename, in an attempt
  31.   to produce a unique filename. Even so, it is still possible for different
  32.   unit names to produce the same filename, and in the unlikely event of this
  33.   happening you get an error message that the unit already exists when you
  34.   try to create the clashing unit name.
  35.  
  36.   Filenames are at most SAFEFNLEN characters long, which on standard Unix
  37.   systems gives you one spare character for making backups or whatever.
  38.  
  39.   It would be better if the B system effectively maintained its own directories
  40.   that mapped units onto files in the real file system, as is done for targets.
  41.   With operating systems with a more limited file system (eg even shorter
  42.   filenames) this is the only possibility.
  43.  
  44.   The B system can operate in two ways: with the interpreter in command,
  45.   and then the editor is called from the interpreter to edit units;
  46.   and with the editor in command, when the editor calls the interpreter to
  47.   execute commands. The variable 'filtered' is Yes when the editor is in
  48.   command, and No otherwise.
  49. */
  50.  
  51. #define COML 60
  52. Hidden char com_line[COML];
  53. #define At_eos(s) ((s)+= strlen(s))
  54.  
  55. Visible Procedure f_edit(fname, errline) value fname; intlet errline; {
  56.     /*The default editor is called with a first parameter of the line number
  57.       and a second parameter of the file name*/
  58.     string cl= com_line; char c;
  59. #ifdef unix
  60.     if (filtered) {
  61.         printf("\001: +%d %s\n", errline, strval(fname));
  62.         fflush(stdout);
  63.         do { c= fgetc(stdin); } while (c != '\n');
  64.         still_ok= Yes; /*ignore interrupts that occurred*/
  65.     } else {
  66.         strcpy(cl, editorfile);
  67.         if (*(cl+strlen(cl)-1) == '+') {
  68.             if (errline != 0) sprintf(At_eos(cl), "%d", errline);
  69.             else *(cl+strlen(cl)-1)= ' ';
  70.         }
  71.         app_fname(At_eos(cl), fname);
  72.         system(com_line);
  73.     }
  74. #else !unix
  75.     fprintf(stderr, "*** Editing units not yet implemented\n");
  76. #endif unix
  77. }
  78.  
  79. #else INTEGRATION
  80.  
  81. Visible Procedure
  82. f_edit(fname, errline, prompt)
  83.     value fname; intlet errline; literal prompt;
  84. {
  85.     string filename= Str(fname);
  86.     btop(&filename, errline, prompt, 0);
  87.     still_ok= Yes;
  88. }
  89.  
  90. #endif
  91.  
  92. Visible bool ws_writable() {
  93.     FILE *f= fopen(tempfile, "w");
  94.     if (f == NULL) return No;
  95.     fclose(f);
  96.     return Yes;
  97. }
  98.  
  99. Hidden bool f_copy(fname, sname) value fname, sname; {
  100.     string fn= strval(fname), sn;
  101.     FILE *fp= fopen(fn, "r"), *sp; int c; bool ok;
  102.     if (fp == NULL) return No;
  103.     sn= strval(sname);
  104.     sp= fopen(sn, "w");
  105.     if (sp == NULL) {
  106.         fclose(fp);
  107.         return No;
  108.     }
  109.     while ((c= getc(fp)) != EOF)
  110.         putc(c, sp);
  111.     fclose(fp);
  112.     ok= fflush(sp) != EOF;
  113.     if (fclose(sp) == EOF)
  114.         ok= No;
  115.     return ok;
  116. }
  117.  
  118. Visible value f_save(fname) value fname; {
  119.     /* saves the file in a temporary file, whose name is returned */
  120.     value sname= mk_text(tempfile);
  121.     VOID f_copy(fname, sname);
  122.     return sname;
  123. }
  124.  
  125. Visible Procedure f_rename(fname, nfname) value fname, nfname; {
  126.     char *f1, f2[100];
  127.     strcpy(f2, strval(nfname));
  128.     unlink(f2);
  129.     f1= strval(fname);
  130. #ifndef RENAME
  131.     link(f1, f2);
  132.     unlink(f1);
  133. #else
  134.     rename(f1, f2);
  135. #endif
  136.     /* what if it fails??? */
  137. }
  138.  
  139. Visible Procedure f_delete(fname) value fname; {
  140.     unlink(strval(fname));
  141. }
  142.  
  143. Visible bool
  144. f_exists(file)
  145.     string file;
  146. {
  147.     FILE *f= fopen(file, "r");
  148.     if (f==NULL) return No;
  149.     fclose(f);
  150.     return Yes;
  151. }
  152.  
  153. #ifndef INTEGRATION
  154.  
  155. Hidden Procedure app_fname(ceos, fname) string ceos; value fname; {
  156.     string fp= strval(fname); intlet k, len= strlen(fp);
  157.     *ceos++= ' ';
  158.     k_Over_len {
  159.         *ceos++= '\\';
  160.         *ceos++= *fp++; /*should really use charval(thof(...))*/
  161.     }
  162.     *ceos= '\0';
  163. }
  164.  
  165. #endif
  166.  
  167. Visible unsigned f_size(ifile) FILE *ifile; {
  168.     long size, ftell();
  169.     fseek(ifile, 0l, 2);
  170.     size= ftell(ifile);
  171.     fseek(ifile, 0l, 0); /* rewind */
  172.     return size;
  173. }
  174.  
  175. Visible Procedure f_close(ofile) FILE *ofile; {
  176.     bool ok= fflush(ofile) != EOF;
  177.     if (fclose(ofile) == EOF || !ok)
  178.         error(MESS(3203, "write error (disk full?)"));
  179. }
  180.  
  181. Visible bool f_interactive(ifile) FILE *ifile; {
  182. #ifdef ISATTY
  183.     return isatty(fileno(ifile));
  184. #else
  185.     return fileno(ifile) < 3;
  186. #endif
  187. }
  188.  
  189. #ifdef IBMPC
  190.  
  191. #define FNMLEN 8
  192. #define TYPLEN 3
  193. #define SPCLEN 1
  194.  
  195. #define FHW "how"
  196. #define FZR "zer"
  197. #define FMN "mon"
  198. #define FDY "dya"
  199. #define FTR "tar"
  200.  
  201. Hidden string
  202. filetype(type)
  203.     literal type;
  204. {
  205.     switch (type) {
  206.         case Zer:    return FZR;
  207.         case Mon:    return FMN;
  208.         case Dya:    return FDY;
  209.         case How:    return FHW;
  210.         case Tar:    return FTR;
  211.         default:    syserr(MESS(3200, "filetype()"));
  212.                 /* NOTREACHED */
  213.     }
  214. }
  215.  
  216. Hidden Procedure
  217. cr_fname(name, type, fname, len, pname)
  218.     value name; string fname, *pname; literal type; int len;
  219. {
  220.     *pname= fname;
  221.     strncpy(*pname, strval(name), len);
  222.     sprintf(fname + len, ".%s", filetype(type));
  223. }
  224.  
  225. #endif IBMPC
  226.  
  227. #ifdef unix
  228.  
  229. #define FNMLEN 12
  230. #define TYPLEN 1
  231. #define SPCLEN 0
  232.  
  233. #define FHW '\''
  234. #define FZR '<'
  235. #define FMN '"'
  236. #define FDY '>'
  237. #define FTR '='
  238.  
  239. Hidden literal
  240. filetype(type)
  241.     literal type;
  242. {
  243.     switch (type) {
  244.         case Zer:    return FZR;
  245.         case Mon:    return FMN;
  246.         case Dya:    return FDY;
  247.         case How:    return FHW;
  248.         case Tar:    return FTR;
  249.         default:    syserr(MESS(3201, "filetype()"));
  250.                 /* NOTREACHED */
  251.     }
  252. }
  253.  
  254. Hidden Procedure
  255. cr_fname(name, type, fname, len, pname)
  256.     value name; string fname, *pname; literal type; int len;
  257. {
  258.     *fname= filetype(type);
  259.     fname[1]= '\0';
  260.     *pname= fname + 1;
  261.     strncat(fname, strval(name), len);
  262. }
  263.  
  264. #endif unix
  265.  
  266. Hidden bool
  267. exists(name)
  268.     string name;
  269. {
  270.     value v= mk_text(name);
  271.     bool exist= in(v, file_names);
  272.     release(v);
  273.     return exist;
  274. }
  275.  
  276. Visible value
  277. new_fname(name, type)
  278.     value name; literal type;
  279. {
  280.     char fname[FNMLEN + TYPLEN + SPCLEN + 1];
  281.     intlet len= length(name);
  282.     string pname;
  283.     if (len > FNMLEN) len= FNMLEN;
  284.     cr_fname(name, type, fname, len, &pname);
  285.     while (exists(fname)) new(pname, len-1);
  286.     return mk_text(fname);
  287. }
  288.  
  289. #include <ctype.h>
  290.  
  291. Hidden Procedure
  292. new(name, n)
  293.     string name; int n;
  294. {
  295.     if (n < 1) error(MESS(3202, "too many units"));
  296.     else if (!isdigit(name[n])) name[n]= '1';
  297.     else if (name[n] != '9') ++name[n];
  298.     else {
  299.         name[n]= '0';
  300.         new(name, --n);
  301.     }
  302. }
  303.